package org.mysfit.ctp4j.infra.utils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.mysfit.ctp4j.core.service.FkDataService;
import org.mysfit.ctp4j.core.service.SkDataService;
import org.mysfit.ctp4j.infra.entity.FkData;
import org.mysfit.ctp4j.infra.entity.SkData;

/**
 * 操作系统信息判断工具类
 * 
 * @author long.gf
 *
 */
public class TradeDataUtils {
	
	public static String REFERSH_SEC = "30";
	
	public static int LAST_SK_COUNT = 30;
	
	public static int LAST_FK_COUNT = 10;

	public static int LAST_5FK_COUNT = 10;

	public static int LAST_15FK_COUNT = 10;
	
	public static Map<String, String> MK_MAP = new HashMap<String, String>();
	
	public static Map<String, BigDecimal> LAST_MK_MAP = new HashMap<String, BigDecimal>();
	
	public static Map<String,List<SkData>> LAST_SK_MAP = new HashMap<String,List<SkData>>();

	public static Map<String,List<FkData>> LAST_FK_MAP = new HashMap<String, List<FkData>>();

	public static Map<String,List<FkData>> LAST_5FK_MAP = new HashMap<String, List<FkData>>();

	public static Map<String,List<FkData>> LAST_15FK_MAP = new HashMap<String, List<FkData>>();
	
	private static 	ThreadPoolExecutor exe;
	
	private static TradeDataUtils dateUtil;
	
	private SkDataService skService;
	
	private FkDataService fkService;

	public static TradeDataUtils getInstance(FkDataService fkService, SkDataService skService) {
		if(null == dateUtil) {
			dateUtil = new TradeDataUtils(fkService, skService);
		}
		return dateUtil;
	}
	
	private TradeDataUtils(FkDataService fkService, SkDataService skService) {
		this.fkService = fkService;
		this.skService = skService;
	}
		
	static {
		exe=new ThreadPoolExecutor(10, 10,
                10L, TimeUnit.MINUTES,
                new LinkedBlockingQueue<Runnable>());
		exe.allowCoreThreadTimeOut(true);
		Runtime.getRuntime().addShutdownHook(new Thread(()-> {
			exe.shutdown();
		}));
	}
	
	
	public void refershSk(SkData sk) {
		String sec = sk.getFtime().substring(sk.getFtime().length()-2);
		if(REFERSH_SEC.equals(sec)) {
			exe.execute(new Runnable() {
				@Override
				public void run() {
						LAST_SK_MAP.clear();
						LAST_SK_MAP.put(sk.getFid(), skService.getLastSkData(sk.getFid(), LAST_SK_COUNT));
				}
			});
		}
	}
	
	public void insertFk(SkData sk) {
		String fid = sk.getFid();
		String ftime = sk.getFtime();
		String day = ftime.substring(0, 10);
		String time = ftime.substring(11);
		String sec = time.substring(time.length()-2);
		if("00".equals(sec)) {
			exe.execute(new Runnable() {
				private String getDiffStartTime(String day ,String time, int diff) {
					Calendar cal = Calendar.getInstance();
					cal.set(Integer.parseInt(day.substring(0, 4)), Integer.parseInt(day.substring(5, 7)), Integer.parseInt(day.substring(8)), Integer.parseInt(time.substring(0,2)), Integer.parseInt(time.substring(3,5)));
					cal.add(Calendar.MINUTE, diff);
					return day + " " + (cal.get(Calendar.HOUR_OF_DAY) < 10 ? "0"+cal.get(Calendar.HOUR_OF_DAY) : cal.get(Calendar.HOUR_OF_DAY))  +":" +  (cal.get(Calendar.MINUTE) < 10 ? "0"+cal.get(Calendar.MINUTE) : cal.get(Calendar.MINUTE)) + ":" + "01";
				}
				@Override
				public void run() {
					String startTime = this.getDiffStartTime(day, time, -1);
					String endTime = day + " " +  time;
					fkService.insertFK(fid,startTime,endTime);
					if("0".equals(time.substring(time.length()-4,time.length()-3)) || "5".equals(time.substring(time.length()-4,time.length()-3))) {
	 					startTime = this.getDiffStartTime(day, time, -5);
						endTime = day + " " + time;
						fkService.insert5FK(fid,startTime,endTime);
					}
					if("15".equals(time.substring(time.length()-5,time.length()-3)) || "30".equals(time.substring(time.length()-5,time.length()-3)) || "45".equals(time.substring(time.length()-5,time.length()-3)) || "00".equals(time.substring(time.length()-5,time.length()-3)) ) {
	 					startTime = this.getDiffStartTime(day, time, -15);
						endTime = day + " " + time;
						fkService.insert15FK(fid,startTime,endTime);
					}
				}
			});
		}
	}
	
	public void refershFk(SkData sk) {
		String sec = sk.getFtime().substring(sk.getFtime().length()-2);
		if(REFERSH_SEC.equals(sec)) {
			exe.execute(new Runnable() {
				@Override
				public void run() {
						String min = sk.getFtime().substring(sk.getFtime().length()-5,sk.getFtime().length()-3);
						LAST_FK_MAP.clear();
						LAST_FK_MAP.put(sk.getFid(), fkService.getLastFkData(sk.getFid(), LAST_FK_COUNT));
						if("0".equals(min.substring(1)) || "5".equals(min.substring(1))) {
							LAST_5FK_MAP.clear();
							LAST_5FK_MAP.put(sk.getFid(), fkService.getLast5FkData(sk.getFid(), LAST_5FK_COUNT));
						}
						if("00".equals(min) || "15".equals(min) || "30".equals(min) || "45".equals(min)) {
							LAST_5FK_MAP.clear();
							LAST_5FK_MAP.put(sk.getFid(), fkService.getLast15FkData(sk.getFid(), LAST_15FK_COUNT));
						}
				}
			});
		}
	}
	
	
	
	public boolean checkUk(String fid, String day, String time) {
		String key = fid + "_" + time;
		if(null == MK_MAP.get(key)) {
			MK_MAP.put(key,  day);
			return true;
		}
		String value = MK_MAP.get(key);
		if(day.equals(value)) {
			return false;
		}
		MK_MAP.clear();
		MK_MAP.put(key,  day);
		return true;
	}
	
}
